package tasks

import contributors.*
import kotlinx.coroutines.*
import java.util.concurrent.CountDownLatch
import java.util.concurrent.atomic.AtomicInteger

//注意在协程中启动新的协程需要在新的coroutine scope中，coroutineScope是一个方法，这个作用域会和父scope绑定，实现一致的声明周期
suspend fun loadContributorsConcurrent(service: GitHubService, req: RequestData): List<User> = coroutineScope {
    //下一步getRepoContributors请求会基于这一步的结果，而且同级别的只有这一个任务在执行，因此这里没必要用async
    val repos = service.getOrgRepos(req.org)
        .also { logRepos(req, it) }
        .body() ?: emptyList()
    //这里的请求具有并发关系，可以使用async来节省时间
    val asyncTasks = mutableListOf<Deferred<List<User>>>()
    repos.forEach { repo ->
        asyncTasks.add(
            async {
//            async(Dispatchers.Default) {
                service.getRepoContributors(req.org, repo.name)
                    .also { logUsers(repo, it) }
                    .body() ?: emptyList()
            }
        )
    }
    //asyncTasks.awaitAll()得到的是List<List<User>>
    asyncTasks.awaitAll().flatten().aggregate()
}